#ifndef _LED_H
#define _LED_H
#include "air32f10x_conf.h"
#include "font.h"
#include "spi1.h"
#include "sys.h"
#include "w25qxx.h"
#include "dac1.h"
#include "tim3.h"

// HUB08接口引脚定义
#define A PBout(0)
#define B PBout(2)
#define C PBout(11)
#define D PBout(13)
#define G1 PBout(15)
#define G2 PAout(12)
#define LAT PBout(6)
#define CLK PBout(8)
// 左边
#define OE PBout(14)
#define R1 PAout(11)
#define R2 PBout(5)

// LED和探针
#define LED PAout(2)

// 接口操作定义
#define DisplayON OE = 0
#define DisplayOFF OE = 1
#define Latch \
    LAT = 1;  \
    LAT = 0

// 参数
#define BUF_SIZE 8
#define SCREEN_WIDTH 64
#define US_PER_ROW 200
#define MS_PER_SHIFT ((uint32_t)20 * 1000 / US_PER_ROW)
#define ZK_OFFSET 0x1000
#define DisplaybufAddr08(row, column) (uint8_t *)((uint32_t)display_buf + (column) + (row) * BUF_SIZE * 2)
#define DisplaybufAddr16(row, column) (uint16_t *)((uint32_t)display_buf + (column) + (row) * BUF_SIZE * 2)
#define Display16bit(row, column, data) *(uint16_t *)((uint32_t)display_buf + (column) + (row) * BUF_SIZE * 2) = __RBIT((uint32_t)(data)) >> 16
#define Display8bit(row, column, data) *(uint8_t *)((uint32_t)display_buf + (column) + (row) * BUF_SIZE * 2) = __RBIT((uint32_t)(data)) >> 24

volatile extern uint16_t display_buf[16 * BUF_SIZE]; // 缓冲区大小

enum WATCH_CMD
{
    WatchReset,
    WatchStart,
    WatchPause,
    WatchStop,
    WatchUpdate,
    WatchGetTime
};

/* 向中断函数传输数据的一个结构 */
struct display_param
{
    uint16_t display_nbit;    // 显示多少个bit
    uint32_t head;            // 循环显存头位于显存哪个位置,头包含数据
    uint32_t tail;            // 循环显存尾位于显存哪个位置,尾不包含数据
    uint8_t *text_buf;        // 文字缓存区,不是点阵
    uint16_t left_shift_time; // 多久左移一位
};

void clear_8x16_to_display_buf(uint16_t position);
void insert_8x16_to_display_buf(uint8_t *buf, uint16_t position);
void insert_16x16_to_display_buf(uint8_t *buf, uint16_t position);
void led_init();

/* 将点阵读到缓冲区 */
uint8_t read_font(uint8_t *buf, uint16_t GB2312_Code);

/* 显示字符 */
void display_text_left_shift(uint8_t *text);
void display_static_text(uint8_t *text);
void static_display_mode();
void led_full_on();
void led_clear_display_buf();
void one_row_led_on(uint8_t row);
uint32_t watch(uint8_t cmd);
void led_update_volleyball_score(uint8_t hit, uint8_t all);
void led_read_font_if_nessessary();
void led_one_row_update();
void led_update_new_task();
void wait_for_left_shift_count(uint8_t n);
uint8_t is_left_shift_count_reached(uint8_t n);
void led_turn_on();
void led_turn_off();
void led_display_infomation_and_wait_once(uint8_t *text);

/* print函数*/
void led_print_dec(uint16_t n, uint8_t position);
void led_print_hex(uint16_t n, uint8_t position);
void led_print_one_ascii(uint8_t ch, uint8_t position);
#endif // !_LED_H